//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

import React, { useEffect, useState } from 'react';
import type { NodeProps } from "reactflow";
import { GitExtraInfo, NodeData } from '../types';
import { get_source, get_type_name, GitSourceInfo, UserDataSourceInfo } from '@/api/user_dataview';
import LocalNodeWrap from '../LocalNodeWrap';
import { Button, Select, Space, Table } from 'antd';
import { get_repo, GitCodeRepo } from '@/api/gitcode/repo';
import { open as shell_open } from '@tauri-apps/api/shell';
import { ExportOutlined, ReloadOutlined } from '@ant-design/icons';
import { list_branch } from '@/api/gitcode/branch';
import { list_tag } from '@/api/gitcode/tag';
import { type GitCodeCommit, list_commit } from '@/api/gitcode/commit';
import type { ColumnsType } from 'antd/lib/table';
import moment from 'moment';

interface RefItem {
    name: string;
    sha: string;
}

const GitCodeCommitListNode = (props: NodeProps<NodeData>) => {

    const [commitList, setCommitList] = useState<GitCodeCommit[]>([]);
    const [repoInfo, setRepoInfo] = useState<GitCodeRepo | null>(null);
    const [refItemList, setRefItemList] = useState<RefItem[]>([]);
    const [curRefItem, setCurRefItem] = useState<RefItem | null>(null);
    const [dataSource, setDataSource] = useState<UserDataSourceInfo | undefined>(undefined);

    const loadDataSource = async () => {
        const res = await get_source(props.data.dataSourceId ?? "");
        setDataSource(res);
    };

    const getSourceTypeName = () => {
        if (dataSource == undefined) {
            return "";
        }
        return get_type_name(dataSource.source_type);
    };

    const loadRepoInfo = async () => {
        if (dataSource == undefined) {
            return;
        }
        const sourceInfo = JSON.parse(dataSource.source_info) as GitSourceInfo;
        const extraInfo = props.data.extraInfo as GitExtraInfo;
        const res = await get_repo(sourceInfo.accessToken, extraInfo.ownerName, extraInfo.repoName);
        setRepoInfo(res);
    };

    const loadRefNameList = async () => {
        if (dataSource == undefined) {
            return;
        }
        const sourceInfo = JSON.parse(dataSource.source_info) as GitSourceInfo;
        const extraInfo = props.data.extraInfo as GitExtraInfo;

        const branchList = await list_branch(sourceInfo.accessToken, extraInfo.ownerName, extraInfo.repoName);
        const tagList = await list_tag(sourceInfo.accessToken, extraInfo.ownerName, extraInfo.repoName);
        const tmpList = [
            ...(branchList.map(item => ({ name: item.name, sha: item.commit.sha }))),
            ...(tagList.map(item => ({ name: item.name, sha: item.commit.sha }))),
        ];
        setRefItemList(tmpList);
        if (curRefItem == null || tmpList.map(item => item.name).includes(curRefItem.name) == false) {
            if (tmpList.length > 0) {
                setCurRefItem(tmpList[0]);
            }
        }
    };

    const loadCommitList = async () => {
        if (dataSource == undefined || curRefItem == null) {
            return;
        }
        const sourceInfo = JSON.parse(dataSource.source_info) as GitSourceInfo;
        const extraInfo = props.data.extraInfo as GitExtraInfo;
        const tmpList = await list_commit(sourceInfo.accessToken, extraInfo.ownerName, extraInfo.repoName, curRefItem.sha);
        setCommitList(tmpList);
    };


    const columns: ColumnsType<GitCodeCommit> = [

        {
            title: "标题",
            render: (_, row: GitCodeCommit) => (
                <a href={row.html_url} target="_blank" rel="noreferrer">{row.commit.message}&nbsp;<ExportOutlined /></a>
            ),
        },
        {
            title: "提交人名称",
            width: 150,
            dataIndex: ["commit", "committer", "name"],
        },
        {
            title: "提交人邮件",
            width: 150,
            dataIndex: ["commit", "committer", "email"],
        },
        {
            title: "提交时间",
            width: 120,
            render: (_, row: GitCodeCommit) => moment(row.commit.committer.date).format("YYYY-MM-DD HH:mm"),
        },
    ];

    useEffect(() => {
        loadDataSource();
    }, []);

    useEffect(() => {
        if (curRefItem != null && dataSource != undefined) {
            loadCommitList();
        }
    }, [curRefItem, dataSource]);

    useEffect(() => {
        if (dataSource != undefined) {
            loadRepoInfo();
            loadRefNameList();
        }
    }, [dataSource]);

    return (
        <LocalNodeWrap title={
            <Space>
                <span>{getSourceTypeName()}</span>
                <span>提交列表</span>
                {repoInfo != null && (
                    <a onClick={e => {
                        e.stopPropagation();
                        e.preventDefault();
                        console.log(repoInfo);
                        shell_open(repoInfo.http_url_to_repo);
                    }}>{repoInfo.full_name}</a>
                )}
                {curRefItem != null && curRefItem.name}
            </Space>
        } nodeData={props} extraButtonList={[
            (
                <Select value={curRefItem?.name ?? ""} onChange={value => {
                    const newItem = refItemList.find(item => item.name == value);
                    if (newItem != undefined) {
                        setCurRefItem(newItem);
                    }
                }}
                    style={{ width: "80px" }}>
                    {refItemList.map(refItem => (
                        <Select.Option key={refItem.name} value={refItem.name}>{refItem.name}</Select.Option>
                    ))}
                </Select>
            ),
            (
                <Button type="text" icon={<ReloadOutlined />} onClick={e => {
                    e.stopPropagation();
                    e.preventDefault();
                    loadCommitList();
                }} title='刷新' />
            ),
        ]} canChangeBgColor={false}>
            <Table rowKey="sha" dataSource={commitList} columns={columns} pagination={false} scroll={{ y: props.data.height - 100 }} className="nodrag nopan nowheel"
            />
        </LocalNodeWrap>
    );
};

export default GitCodeCommitListNode;